(선택적 체이닝)에 대하여 알아보겠습니다.
# ES 2020, optional chaining 옵셔널 체이닝
ES 6 이 후 추가된 여러 기능들 중에서
Optional chaining은 매우 유용하고 선호도가 높은 기능 중 하나가 아닐까 생각됩니다. 그만큼 많이 쓰이고 있는 Optional chaining은 사전적 의미처럼 객체에 대하여
선택적으로 체이닝을 수행하는 연산자입니다. 쉽게 설명하면 객체가 가진 프로퍼티의 존재 여부에 따라 값을 사용할 수 있습니다.
그럼 이를 설명하기 이해서 아래와 같이 객체 myObj를 만들고 알아봅니다.
myObj = {
a: {
aa: 1
}
}
yourNum = myObj.a.aa
// Result
1
위 코드를 살펴보면 객체 myObj는 프로퍼티 a를 가지고 있고 a 역시 객체 { aa: 1 }을 가지고 있죠. 아래에서는 새로운 변수 yourNum을 만들고 myObj.a.aa의 값을 선언했습니다. 결과를 확인해보니 에러 없이 정상적으로 잘 동작했습니다.
"만약 myObj 내부에 a 또는 aa의 값이 존재하지 않는다면?"
하지만 상황에 따라 객체의 프로퍼티는 존재하지 않을 수도 있습니다. 즉 서버 API를 통해 값을 내려받는 경우라면 프로퍼티가 항상 존재하는지 알 수 없을 것입니다. 실제로 값이 없다면 아래와 같이 에러가 발생합니다...
yourObj = myObj.a.aa
// 에러 발생
VM576:1 Uncaught TypeError: Cannot read properties of undefined (reading 'aa') at <anonymous>:1:17 (anonymous)
@ 많이 사용해온 해결 방법들
이런 문제를 해결하기 위해서
번거롭고 가독성을 저해하는 다양한 방법이 사용되었는데요 ~ 아래와 같이 사용된 코드를 많이 봤었고 작성했었습니다...
if ('a' in myObj) {
if ('aa' in myObj.a) {
yourNum = myObj.a.aa
}
}
또는...
if (myObj.hasOwnProperty('a')) {
// a 프로퍼티를 가진 경우에만 실행
...
}
아니면 이렇게도 사용했죠.
yourNum = myObj.a && myObj.a.aa
결국 에러가 발생하지 않도록 객체 내부의 프로퍼티 존재 여부를 확인하는 과정들입니다. 위 방법들 외에도 Lodash 메소드를 사용할 수도 있습니다. _.get()을 사용한다면 아래와 같이 작성 가능합니다.
yourNum = _.get(myObj, 'a.aa')
얘기가 너무 길어졌습니다... 이제 Optional Chaining을 사용하면 위 코드가 어떻게 바뀌게 되는지 바로 알아보겠습니다.
! Optional Chaining 적용 예제
위 코드를 Optional Chaning을 사용 방법은 매우 간단합니다. 바로
객체의 프로퍼티 뒤에 ?를 추가하면 됩니다. 즉 위 코드에 Optional Chaining을 사용할 경우 아래와 같이 표기할 수 있습니다.
yourNum = myObj.a?.aa
// Result
1
yourNum = myObj.b?.aa
// Result, 값이 없으므로 undefined
undefined
위 예제 중 아래 코드는 만약 프로퍼티가 존재하지 않는 경우입니다. 이 경우
undefined의 값을 선언되며 런타임 에러도 발생하지 않기 때문에 매우 유용한 방법입니다. 기존의 모든 코드들 역시 이 방법을 적용할 경우
코드 길이를 줄이고 가독성을 높여줄 수 있습니다.
여기까지 Optional Chaining에 대하여 간략하게 알아보았습니다.
참고로 ES 6 이 후의 문법들은 라이브 환경의 배포시 babel 등의 트랜스파일러를 사용해 이 전 문법으로 변환해 사용되죠. 개발 환경에 따라 이런 과정이 필요할 수 있으니 참고하세요.